package com.lcf.app.shiro.config;

import cn.hutool.core.util.RandomUtil;
import com.lcf.app.shiro.common.MyRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * @author ChenFei
 * @date 2021/11/2
 */
@Configuration
public class ShiroConfig {

    @Bean
    public Realm realm() {
        MyRealm realm = new MyRealm();
        realm.setCredentialsMatcher(credentialsMatcher());//加密验证方式
        return realm;
    }

    /**
     * 功能描述：ShiroFilterChainDefinition将任何特定于应用程序的路径映射到给定的过滤器，以允许不同的路径进行不同级别的访问。
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        //不需要拦截的路径
        chainDefinition.addPathDefinition("/user/login", "anon");
        // 以“admin”角色登录的用户
        //chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");
        // 具有'document:read'权限的登录用户
        //chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");
        // 所有其他路径都需要登录用户
        chainDefinition.addPathDefinition("/**", "authc");
        return chainDefinition;
    }

    /**
     * shiro缓存设置
     *
     * @return
     */
    @Bean
    protected CacheManager cacheManager() {
        return new MemoryConstrainedCacheManager();
    }


    /**
     * 设置加密、验证方式
     *
     * @return
     */
    private HashedCredentialsMatcher credentialsMatcher() {
        HashedCredentialsMatcher hashMatcher = new HashedCredentialsMatcher();
        hashMatcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);//md5加密
        hashMatcher.setStoredCredentialsHexEncoded(true);// 存储散列后的密码是否为16进制
        hashMatcher.setHashIterations(1024);// 加密次数
        return hashMatcher;
    }

    /**
     * 测试：生成测试盐和密码
     *
     * @param args
     */
    public static void main(String[] args) {
        String s = RandomUtil.randomString(32);
        String result = new Md5Hash("123456", s, 1024).toString();
        System.out.println("salt : " + s + " , password : " + result);
    }

}
